package reflect.filew;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.UnsupportedEncodingException;
import java.util.Iterator;

import object.model.JavaFile;
import object.model.JavaVariables;
import object.model.TableType;
import reflect.engine.DataBaseStructInfoer;
import system.Sys_Config;


public class JavaFileWritter {
	
	private static final String nextline = "\n";
	private static final String locate = Thread.currentThread().getContextClassLoader()
		.getResource("").getPath().substring(1).replaceFirst("bin", "src");
	private static final String javaFileSuff = ".java";
	
	public void toWriteJavaFile(JavaFile jf){
		//		
		String location = this.genLocate(jf.getPackageName());
		String fileContent = this.genJavaFileString(jf);
		//
		this.write(fileContent, location, this.frontCharUpper(jf.getClassName()), javaFileSuff);		
	}	
	
	public static String genLocate(String packageName){
		String loc = "";
		loc += locate + File.separator;
		if(packageName!=null){
			String[] s = packageName.split("\\.");
			for(int i=0;i<s.length;i++){
				loc += s[i] + File.separator;
			}			
		}else{
			loc = null;
		}
		return loc;
	}
	
	public void write(String content, String dir, String filename, String suffix){
		File fdir = new File(dir);
		File fi = new File(dir+File.separator+filename+suffix);
		if(!fdir.exists()){
			fdir.mkdirs();
		}		
		try {
			FileOutputStream fos = new FileOutputStream(fi);
			BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(fos,Sys_Config.DB_DEFAULT_ENCODING));
			bw.write(content);
			bw.close();
			fos.close();
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (UnsupportedEncodingException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}		
	}
	
	public String genJavaFileString (JavaFile jf){
		String str = "" + nextline;
		str += this.genFileHead(jf) + nextline;
		str += this.genDDLTail(jf) + nextline;
		str += this.genClassBody(jf) + nextline;		
		return str;
	}
	
	private String genClassBody(JavaFile jf){
		String body = "";
		body += "public class "+ this.frontCharUpper(jf.getClassName())+"{" + nextline;
		body += this.genVariables(jf) + nextline;
		body += this.genGetsAndSets(jf) + nextline;
		body += "}" + nextline;
		return body;
	}
	
	private String genVariables(JavaFile jf){
		String vars = "";
		Iterator<JavaVariables> iter = jf.getVars().iterator();
		while(iter.hasNext()){
			JavaVariables item = iter.next();
			vars += "\tprivate " + item.getClassSimpName() + " " + item.getVarName() + ";" +
					" //mysqlType:"+item.getMysqlDataType() + "-Condiction:" + item.getCondiction() +
					"-KEY:" + ((item.isPrimaryKey())?"PRI":"NOR") + nextline;
		}
		return vars;
	}
	
	private String genGetsAndSets(JavaFile jf){
		String gs = "";
		Iterator<JavaVariables> iter = jf.getVars().iterator();
		while(iter.hasNext()){
			JavaVariables item = iter.next();
			gs += this.genGetter(item.getClassSimpName(),item.getVarName() ) + nextline;
			gs += this.genSetter(item.getClassSimpName(),item.getVarName() ) + nextline;
		}
		return gs;
	}
	
	private String genFileHead(JavaFile jf){
		String head = "";
		head += "package " + jf.getPackageName() + ";"+nextline;
		Iterator<String> iter = jf.getImporters().iterator();
		while(iter.hasNext()){
			String str = iter.next();
			head += "import "+str+";"+nextline;
		}
		return head;
	}
	
	private String genSetter(String type, String name){
		String setter = "";
		setter += "\tpublic void set" + this.frontCharUpper(name) + "("+type+" "+ name +"){"+nextline;
		setter += "\t\tthis."+name+" = "+ name +";"+nextline;
		setter += "\t}" + nextline;		
		return setter;
	}
	
	private String genGetter(String type, String name){
		String getter = "";
		getter += "\tpublic " + type + " get" + this.frontCharUpper(name) + "(){"+nextline;
		getter += "\t\treturn this."+name+";"+nextline;
		getter += "\t}" + nextline;		
		return getter;
	}
	
	private String frontCharUpper(String str){
		return str.substring(0, 1).toUpperCase() + str.substring(1);
	}
	
	private String genDDLTail(JavaFile jf){
		if(jf.getType() == TableType.TABLE){
			return "";
		}else if(jf.getType() == TableType.VIEW){
			String ddlTail = "//DDL:";
			ddlTail += new DataBaseStructInfoer().getTableDDL(jf.getClassName(), jf.getType()).getCreateTable();
			return ddlTail;
		}else{
			return "";
		}
	}
}
